/**
 * @file voice_uart.c
 * @author your name (you@domain.com)
 * @brief
 * @version 0.1
 * @date 2023-07-24
 *
 * @copyright Copyright (c) 2023
 *
*/
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <FreeRTOS.h>
#include <timers.h>
#include <task.h>
#include "bflb_uart.h"
#include "bflb_gpio.h"
#include "voice_uart.h"
#include "log.h"
#include "homeAssistantPort.h"

#define GBD_TAG "UART"

static void uart_init(void);

#define MQTT_TOPIC          "ha/ai/light"
#define MQTT_MSG_OPEN_L     "{\"status\":1}"
#define MQTT_MSG_CLOSE_L    "{\"status\":0}"

uart_rx_cmd_t uart_cmd;
static struct bflb_device_s* uart1;
static char uart_buff[5] = { 0 };

static const uart_data_t g_uart_buf[] = {
  {{0xA1, 0x00, 0x00, 0x00, 0xFF}, 5}, //wakeup_uni
  {{0xA1, 0x00, 0x01, 0x01, 0xFF}, 5}, //openL
  {{0xA1, 0x00, 0x01, 0x00, 0xFF}, 5}, //closeL
};

void voice_uart_task(void* arg)
{

    uart_init();
    while (1) {
        vTaskDelay(1000/portTICK_PERIOD_MS);
    }
}

static int voice_cmd_check(char* buff, int len)
{

    int data_cnt = 0, j = 0;
    // char* uart_txbuf = pvPortMalloc(4);
    // memset(uart_txbuf, 0, 4);
    while (1) {
        for (size_t i = 0; i < 5; i++)
        {
            if (buff[i]==g_uart_buf[j].data[i]) data_cnt++;
            else break;
        }
        if (data_cnt==g_uart_buf->len) break;
        data_cnt = 0;
        j++;
        if (j>23) return -1;
    }
    LOG_I("check uart cmd=%d", j);
    return j;
}

static void uart_isr(int irq, void* arg)
{
    uint32_t intstatus = bflb_uart_get_intstatus(uart1);
    if (intstatus & UART_INTSTS_RX_FIFO) {
        LOG_I("rx fifo\r\n");
        memset(uart_buff, 0, 5);
        int index = 0;
        while (bflb_uart_rxavailable(uart1)) {
            // LOG_I("0x%02x\r\n", bflb_uart_getchar(uart1));
            uart_buff[index++] =  bflb_uart_getchar(uart1);
        }
         LOG_I("uart recv:%02X %02X %02X %02X %02X", uart_buff[0], uart_buff[1], uart_buff[2], uart_buff[3], uart_buff[4]);

        uart_cmd = voice_cmd_check(uart_buff, 4);

        switch (uart_cmd)
        {
            case UART_RX_CMD_OPENL:
            {
                LOG_I("Voice cmd: [打开灯光]");
                homeAssistant_mqtt_port_public(MQTT_TOPIC, MQTT_MSG_OPEN_L, 1,1);
            }
            break;
            case UART_RX_CMD_CLOSEL:
            {
                LOG_I("Voice cmd: [关闭灯光]");
                homeAssistant_mqtt_port_public(MQTT_TOPIC, MQTT_MSG_CLOSE_L, 1, 1);
            }
            break;
            default:
                break;
        }
        uart_cmd = UART_RX_CMD_NONE;
    }
}
/**
 * @brief
 *
*/
static void uart_init(void)
{
    struct bflb_device_s* gpio;
    struct bflb_uart_config_s cfg = {
        .baudrate = 115200,
        .data_bits = UART_DATA_BITS_8,
        .stop_bits = UART_STOP_BITS_1,
        .parity = UART_PARITY_NONE,
        .flow_ctrl = 0,
        .tx_fifo_threshold = 4,
        .rx_fifo_threshold = 4,
    };

    gpio = bflb_device_get_by_name("gpio");
    uart1 = bflb_device_get_by_name("uart1");

    bflb_gpio_uart_init(gpio, GPIO_PIN_25, GPIO_UART_FUNC_UART1_TX);
    bflb_gpio_uart_init(gpio, GPIO_PIN_26, GPIO_UART_FUNC_UART1_RX);

    bflb_uart_init(uart1, &cfg);

    bflb_uart_txint_mask(uart1, false);
    bflb_uart_rxint_mask(uart1, false);
    bflb_irq_attach(uart1->irq_num, uart_isr, NULL);
    bflb_irq_enable(uart1->irq_num);
    LOG_I("VOICE_UART_INITED");
}